package com.heima.user.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.apis.article.IArticleClient;
import com.heima.file.service.FileStorageService;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.dtos.*;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.mapper.ApUserMapper;
import com.heima.user.service.ApUserService;
import com.heima.utils.common.AppJwtUtil;
import com.heima.utils.common.PhoneUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.file.FileStore;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
@Transactional
@Slf4j
public class ApUserServiceImpl extends ServiceImpl<ApUserMapper, ApUser> implements ApUserService {

    @Resource
    private ApUserMapper apUserMapper;
    @Resource
    private ApUserFanMapper apUserFanMapper;
    @Resource
    private ApUserFollowMapper apUserFollowMapper;
    @Resource
    private FileStorageService fileStorageService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private IArticleClient articleClient;
    /**
     * app端登录功能
     * @param dto
     * @return
     */
    @Override
    public ResponseResult login(LoginDto dto) {
        //1.正常登录 用户名和密码
        if(StringUtils.isNotBlank(dto.getPhone()) && StringUtils.isNotBlank(dto.getPassword())){
            //1.1 根据手机号查询用户信息
            ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, dto.getPhone()));
            if(dbUser == null){
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST,"用户信息不存在");
            }

            //1.2 比对密码
            String salt = dbUser.getSalt();
            String password = dto.getPassword();
            String pswd = DigestUtils.md5DigestAsHex((password + salt).getBytes());
            if(!pswd.equals(dbUser.getPassword())){
                return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_PASSWORD_ERROR);
            }

            //1.3 返回数据  jwt  user
            String token = AppJwtUtil.getToken(dbUser.getId().longValue());
            Map<String,Object> map = new HashMap<>();
            map.put("token",token);
            dbUser.setSalt("");
            dbUser.setPassword("");
            map.put("user",dbUser);

            return ResponseResult.okResult(map);
        }else {
            //2.游客登录
            Map<String,Object> map = new HashMap<>();
            map.put("token",AppJwtUtil.getToken(0L));
            return ResponseResult.okResult(map);
        }


    }



    @Override
    public ResponseResult getUserInfo(Integer userId) {
        if(userId==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApUser user = getById(userId);
        if(user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        Long fansCount= Long.valueOf(apUserFanMapper.selectCount(Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId, userId)));
        Long followCount= Long.valueOf(apUserFollowMapper.selectCount(Wrappers.<ApUserFollow>lambdaQuery().eq(ApUserFollow::getUserId, userId)));
        UserDto dto = new UserDto();

        // 转换为PublicUserDto，过滤敏感信息
        PublicUserDto publicUser = new PublicUserDto();
        publicUser.setId(user.getId());
        publicUser.setName(user.getName());
        publicUser.setImage(user.getImage());
        publicUser.setSex(user.getSex());
        publicUser.setCertification(user.getCertification());
        publicUser.setIdentityAuthentication(user.getIdentityAuthentication());
        publicUser.setStatus(user.getStatus());
        publicUser.setFlag(user.getFlag());
        publicUser.setCreatedTime(user.getCreatedTime());

        dto.setUser(publicUser);
        dto.setFansCount(fansCount);
        dto.setFollowCount(followCount);

        return ResponseResult.okResult(dto);
    }

    @Override
    public ResponseResult getUserFansList(Integer userId, Integer page, Integer size) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (page == null || page <= 0) {
            page = 1;
        }

        if (size == null || size <= 0 || size > 50) {
            size = 10;
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 分页查询粉丝列表
        Page<ApUserFan> fanPage = new Page<>(page, size);
        fanPage.setSearchCount(true);
        Page<ApUserFan> resultPage = apUserFanMapper.selectPage(fanPage,
                Wrappers.<ApUserFan>lambdaQuery()
                        .eq(ApUserFan::getUserId, userId)
                        .orderByDesc(ApUserFan::getCreatedTime));

        return ResponseResult.okResult(resultPage);
    }

    @Override
    public ResponseResult getUserFollowList(Integer userId, Integer page, Integer size) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (page == null || page <= 0) {
            page = 1;
        }

        if (size == null || size <= 0 || size > 50) {
            size = 10;
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 分页查询关注列表
        Page<ApUserFollow> followPage = new Page<>(page, size);
        followPage.setSearchCount(true);
        Page<ApUserFollow> resultPage = apUserFollowMapper.selectPage(followPage,
                Wrappers.<ApUserFollow>lambdaQuery()
                        .eq(ApUserFollow::getUserId, userId)
                        .orderByDesc(ApUserFollow::getCreatedTime));

        return ResponseResult.okResult(resultPage);
    }



    @Override
    public ResponseResult isFollowedByUser(Integer userId, Integer followId) {
        // 参数校验
        if (userId == null || followId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        ApUser followUser = getById(followId);
        if (followUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "被关注用户不存在");
        }

        // 查询是否已关注
        Integer count = apUserFollowMapper.selectCount(
                Wrappers.<ApUserFollow>lambdaQuery()
                        .eq(ApUserFollow::getUserId, userId)
                        .eq(ApUserFollow::getFollowId, followId)
        );

        Map<String, Boolean> result = new HashMap<>();
        result.put("isFollowed", count > 0);

        return ResponseResult.okResult(result);
    }

    @Override
    public ResponseResult followUser(Integer userId, FollowDto followDto) {
        // 参数校验
        if (userId == null || followDto == null || followDto.getFollowId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "参数不能为空");
        }

        Integer followId = followDto.getFollowId();
        if (userId.equals(followId)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "不能关注自己");
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        ApUser followUser = getById(followId);
        if (followUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "被关注用户不存在");
        }

        // 判断是关注还是取消关注
        if (followDto.getIsFollow()) {
            // 关注操作
            Integer count = apUserFollowMapper.selectCount(
                    Wrappers.<ApUserFollow>lambdaQuery()
                            .eq(ApUserFollow::getUserId, userId)
                            .eq(ApUserFollow::getFollowId, followId)
            );

            if (count <= 0) {
                // 未关注，执行关注操作
                ApUserFollow apUserFollow = new ApUserFollow();
                apUserFollow.setUserId(userId);
                apUserFollow.setFollowId(followId);
                apUserFollow.setFollowName(followUser.getName());
                apUserFollow.setCreatedTime(new Date());
                apUserFollow.setLevel((short) 1); // 默认关注度为1
                apUserFollow.setIsNotice((short) 1); // 默认开启通知
                apUserFollowMapper.insert(apUserFollow);

                // 同时在粉丝表中添加记录
                ApUserFan apUserFan = new ApUserFan();
                apUserFan.setUserId(followId);
                apUserFan.setFansId(userId);
                apUserFan.setFansName(user.getName());
                apUserFan.setCreatedTime(new Date());
                apUserFan.setLevel((short) 0); // 默认忠实度为0
                apUserFan.setIsDisplay((short) 1); // 默认可见动态
                apUserFan.setIsShieldLetter((short) 0); // 默认不屏蔽私信
                apUserFan.setIsShieldComment((short) 0); // 默认不屏蔽评论
                apUserFanMapper.insert(apUserFan);
            }
        } else {
            // 取消关注操作
            apUserFollowMapper.delete(
                    Wrappers.<ApUserFollow>lambdaQuery()
                            .eq(ApUserFollow::getUserId, userId)
                            .eq(ApUserFollow::getFollowId, followId)
            );

            // 同时在粉丝表中删除记录
            apUserFanMapper.delete(
                    Wrappers.<ApUserFan>lambdaQuery()
                            .eq(ApUserFan::getUserId, followId)
                            .eq(ApUserFan::getFansId, userId)
            );
        }

        return ResponseResult.okResult(null);
    }

    @Override
    public ResponseResult isFollowMe(Integer userId, Integer fanId) {
        // 参数校验
        if (userId == null || fanId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        ApUser fanUser = getById(fanId);
        if (fanUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "粉丝用户不存在");
        }

        // 查询目标用户是否关注了当前用户（即是否互相关注）
        Integer count = apUserFollowMapper.selectCount(
                Wrappers.<ApUserFollow>lambdaQuery()
                        .eq(ApUserFollow::getUserId, fanId)
                        .eq(ApUserFollow::getFollowId, userId)
        );

        Map<String, Boolean> result = new HashMap<>();
        result.put("isFollowMe", count > 0);

        return ResponseResult.okResult(result);
    }

    @Override
    public ResponseResult uploadAvatar(MultipartFile multipartFile, Integer userId) throws IOException {
        if(multipartFile == null||multipartFile.getSize()==0){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "请选择图片");
        }
        if(userId== null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }
        ApUser user = getById(userId);
        if(user == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }
        try{
            String fileName = UUID.randomUUID().toString().replace("-", "");
            String originalFilename = multipartFile.getOriginalFilename();
            String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            String fileId = fileStorageService.uploadImgFile("", fileName + suffix, multipartFile.getInputStream());
            user.setImage(fileId);
            updateById(user);
            Map<String, String> result = new HashMap<>();
            result.put("imageUrl", fileId);
            return ResponseResult.okResult(result);
        }catch(Exception e){


            e.printStackTrace();
        }
        return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR);
    }

    @Override
    public ResponseResult sendCode(String phone, HttpSession session) {
        if(!PhoneUtil.isPhoneValid( phone)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "手机号格式错误");
        }
        String code = RandomUtil.randomNumbers(6);
        stringRedisTemplate.opsForValue().set("code:"+phone, code, 1, TimeUnit.MINUTES);
        log.debug("发送验证码成功，验证码为：{}", code);
        return ResponseResult.okResult(null);
    }

    @Override
    public ResponseResult codeLogin(LoginFormDTO loginForm, HttpSession session) {

        if(!PhoneUtil.isPhoneValid( loginForm.getPhone())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "手机号格式错误");
        }
        String code = loginForm.getCode();
        String redisCode = stringRedisTemplate.opsForValue().get("code:" + loginForm.getPhone());
        if(!code.equals(redisCode)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "验证码错误");
        }

        ApUser dbUser = getOne(Wrappers.<ApUser>lambdaQuery().eq(ApUser::getPhone, loginForm.getPhone()));

        // 如果用户不存在，则创建新用户
        if (dbUser == null) {
            dbUser = new ApUser();
            dbUser.setPhone(loginForm.getPhone());
            dbUser.setName("用户" + loginForm.getPhone().substring(7)); // 默认用户名
            dbUser.setSalt(""); // 无密码登录，盐值为空
            dbUser.setPassword(""); // 无密码登录，密码为空
            dbUser.setStatus(true); // 默认状态正常
            dbUser.setFlag((short) 0); // 默认普通用户
            dbUser.setCreatedTime(new Date());
            save(dbUser);
        }
        String token = AppJwtUtil.getToken(dbUser.getId().longValue());
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);

        // 清除敏感信息
        dbUser.setSalt("");
        dbUser.setPassword("");
        map.put("user", dbUser);

        // 删除已使用的验证码
        stringRedisTemplate.delete("code:" + loginForm.getPhone());

        return ResponseResult.okResult(map);
    }

    // 在 ApUserServiceImpl.java 中添加以下方法

    @Override
    public ResponseResult getUserCollections(Integer userId, Integer page, Integer size) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (page == null || page <= 0) {
            page = 1;
        }

        if (size == null || size <= 0 || size > 50) {
            size = 10;
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 调用文章服务获取收藏的文章列表
        ResponseResult responseResult = articleClient.getUserCollections(userId, page, size);

        return responseResult;
    }

    @Override
    public ResponseResult getUserLikedArticles(Integer userId, Integer page, Integer size) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (page == null || page <= 0) {
            page = 1;
        }

        if (size == null || size <= 0 || size > 50) {
            size = 10;
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 调用文章服务获取点赞的文章列表
        ResponseResult responseResult = articleClient.getUserLikedArticles(userId, page, size);

        return responseResult;
    }

    @Override
    public ResponseResult likeArticle(Integer userId, Long articleId, Boolean isLike) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (articleId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章ID不能为空");
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 调用文章服务进行点赞操作
        ResponseResult responseResult = articleClient.likeArticle(userId, articleId, isLike);
        return responseResult;
    }

    @Override
    public ResponseResult isArticleLiked(Integer userId, Long articleId) {
        // 参数校验
        if (userId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "用户ID不能为空");
        }

        if (articleId == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章ID不能为空");
        }

        // 检查用户是否存在
        ApUser user = getById(userId);
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "用户不存在");
        }

        // 调用文章服务查询点赞状态
        ResponseResult responseResult = articleClient.isArticleLiked(userId, articleId);
        return responseResult;
    }




}
